/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 random_number_generator.h

	$Header: /heroes4/random_number_generator.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( RANDOM_NUMBER_GENERATOR_H_INLCUDED )
#define RANDOM_NUMBER_GENERATOR_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <assert.h>

/////////////////////////////////////////////////////////////////////////////
// t_random_number_generator class

class t_random_number_generator
{
public:
	// Constructor
	t_random_number_generator( long seed = 1L ) : m_seed( seed ) {}

	// Operator
	int  operator()();

	template <typename type>
	type operator()( type limit )
	{
		return type(operator()() % limit);
	}

	template <typename type>
	type operator()( int low, type high )
	{
		return type( operator()() % (high - low + 1) + low );
	}

	double operator()( double limit);
	double operator()( double low, double high);

	long get_seed() const;
	void set_seed( long seed );

private:
	// Data members
	long	m_seed;
};

/////////////////////////////////////////////////////////////////////////////
inline int t_random_number_generator::operator()()
{
	m_seed = m_seed * 214013L + 2531011L;
	return ( m_seed >> 16 ) & 0x7fff;
}

/////////////////////////////////////////////////////////////////////////////
inline long t_random_number_generator::get_seed() const
{
	return m_seed;
}

inline void t_random_number_generator::set_seed( long seed )
{
	m_seed = seed;
}

inline double t_random_number_generator::operator()( double limit)
{
	// % doesn't work for doubles, so compute manually
	int random = operator()();

	double div = (double)random / (double)(0x7fff);

	assert(div <= 1.0);
	assert(div >= 0.0);

	return limit * div;
}

inline double t_random_number_generator::operator()( double low, double high)
{
	double base = operator()(high - low);
	return base + low;
}

#endif // !defined( RANDOM_NUMBER_GENERATOR_H_INLCUDED )
